/********************************************************************
 *@brief Implement basic object classes and provide universal capabilities
 *@author wcf
 *@date 2025-01-11
********************************************************************/

#ifndef __CS_OBJECT_H__
#define __CS_OBJECT_H__

#include "cscoreglobal.h"
#include "csvariant.h"
#include "csproperty.h"
#include "csmethod.h"
#include <iostream>
#include "csnotify.h"
#include <list>

CS_NAMESPACE_BEGIN

#define CS_OBJECT(Class)\
    public:\
        virtual const char* className() const { return #Class; }

class csObject;
class CSCORE_EXPORT csObjectNotify : public csNotify
{
public:
    csObjectNotify(int type, csObject* pSender)
        : csNotify(type, pSender) {}
};

class CSCORE_EXPORT csDestroyNotify : public csObjectNotify
{
public:
    csDestroyNotify(csObject* pSender);
};

class csObject;
using csObjectList = csList<csObject*>;
class csObjectData;
class CSCORE_EXPORT csObject
{
    CS_OBJECT(csObject)
public:
    enum NotifyType
    {
        CS_NOTIFY_BEGIN(csObject) = 0,
        Destroy,
        CS_NOTIFY_END(csObject)
    };
    CS_NOTIFY_VOLID_DECL(csObject);
public:
	explicit csObject(csObject* pParent = nullptr);
	virtual ~csObject();
    csString objectName() const;
    void setObjectName(const csString& objectName);
    csObject* parent() const;
    void setParent(csObject* pObject);

    bool hasProperty(const char* name) const;
    csVariant property(const char* name) const;
    void setProperty(const char* name, const csVariant& value);
    csVariantMap propertys() const;
    bool hasMemberProperty(const char* name) const;
    csVariant memberProperty(const char* name) const;
    void setMemberProperty(const char* name, const csVariant& value);
    csVariantMap memberPropertys() const;
    bool hasValueProperty(const char* name) const;
    csVariant valueProperty(const char* name) const;
    void setValueProperty(const char* name, const csVariant& value);
    csVariantMap valuePropertys() const;
    void removeValueProperty(const char* name);
    void clearValuePropertys();
    //method
    bool hasMethod(const char* signature) const;
    bool invoke(const char* method,
        csGenericReturnArgument ret,
        csGenericArgument arg1 = csGenericArgument(),
        csGenericArgument arg2 = csGenericArgument(),
        csGenericArgument arg3 = csGenericArgument(),
        csGenericArgument arg4 = csGenericArgument(),
        csGenericArgument arg5 = csGenericArgument());
    bool invoke(const char* method,
        csGenericArgument arg1 = csGenericArgument(),
        csGenericArgument arg2 = csGenericArgument(),
        csGenericArgument arg3 = csGenericArgument(),
        csGenericArgument arg4 = csGenericArgument(),
        csGenericArgument arg5 = csGenericArgument());
    //notify
    virtual void attach(csObject* pObject);
    virtual void detach(csObject* pObject);
    virtual void installFilter(csObject* pObject);
    virtual void removeFilter(csObject* pObject);
protected:
	void registerProperty(const csString& name, csGenericProperty* pProperty);
    bool registerMethod(const std::string& name, csGenericMethod* method);
    std::string generateSignature(const char* method, const std::list<csGenericArgument>& args);
    virtual void send(csNotify* pNotify);
    virtual bool dishFilter(csNotify* pNotify);
    virtual void dishReciver(csNotify* pNotify);
    virtual bool filter(csNotify* pNotify);
    virtual void recive(csNotify* pNotify);
    virtual void reciveDestroy(csDestroyNotify* pNotify);
private:
    CS_DISABLE_COPY(csObject)
    csObjectData* m_d = nullptr;
};

CS_NAMESPACE_END

#endif // !__CS_OBJECT_H__
